import json
import threading
import uuid
from datetime import datetime

from domain.consts import user_context
from domain.mapper.spider_result import SpiderResult
from domain.mapper.spider_task import SpiderTask
from domain.mapper.spider_user import SpiderUser
from domain.page import Page
from domain.resp import Resp
from domain.run_info import RunInfo
from domain.spider_params import SpiderParams
from domain.user import User
from eshoputils.browser_utils import get_task_dir
from eshoputils.mysql_util import MySqlUtil
from graph.graph import EshopAssistantGraph

def compared(x):
    firsturl = x[0]
    return int(firsturl.rsplit('/', 1)[-1].split('.')[0].split('_')[0])

class EShopAssistantService:

    def update_spider_info(self, info:SpiderParams):
        user_id = user_context.get()
        delete_sql = f"delete from spider_param where user_id = '{user_id}'"
        insert_sql = "insert into spider_param (id, shop_urls, key_words, product_urls, user_id, shop_keywords) values (:id, :su, :ky, :pu, :ui, :sk)"
        MySqlUtil.bantch_execut([(delete_sql, None), (insert_sql, {'id':uuid.uuid4().hex, 'su':info.shop_urls, 'ky' : info.key_words, "pu":info.product_urls, "ui":user_id, "sk":json.dumps(info.shop_keywords, ensure_ascii=False)})])
        return Resp.ok()

    def run(self, run_info : RunInfo):
        # res = SpiderTask.select_task_by("运行中")
        # tasks = []
        # for r in res:
        #     tasks.append(r)
        # if tasks:
        #     return Resp.error(msg="当前有任务正在运行，请等当前任务运行完成后再执行")
        work_dir = get_task_dir()
        if not work_dir:
            return Resp.error(msg="当前有任务队列已满，请稍后再试")
        task_id = uuid.uuid4().hex
        task_name = f"任务-{datetime.now().strftime('%Y-%m-%d %H-%M-%S')}"
        SpiderTask.insert_task(**{
            "id":task_id,
            'task_configuration':run_info.dict(),
            'task_state':'运行中',
            'task_name':task_name,
            'task_info':'',
            'create_time':datetime.now(),
            'user_id':user_context.get()
        })
        threading.Thread(target=EshopAssistantGraph.start_graph, args=(task_id, run_info, work_dir, user_context.get())).start()
        return Resp.ok(data={'task_id':task_id})

    def get_task_info(self, task_id : str):
        info = SpiderTask.select_task(task_id)[0]
        if '运行中' != info.task_state:
            return Resp.ok(data = {"info" : info.task_info})
        task_state = EshopAssistantGraph.graph.get_state({"configurable": {"thread_id": task_id}}).values
        return Resp.ok(data = {"info" : '<br>'.join(task_state['task_info'])})

    def get_task_result(self, task_id : str):
        task_result = {}
        result = SpiderResult.select_list(task_id)
        for product_result in result:
            platform_level = task_result.get(product_result.platform, {})
            task_result[product_result.platform] = platform_level
            crawl_type_level = platform_level.get(product_result.crawl_type, {})
            platform_level[product_result.crawl_type] = crawl_type_level
            if product_result.crawl_type == "店铺-关键字":
                ts = product_result.target_name.strip().split("/")
                targtename = " : ".join(ts)
            else:
                targtename = product_result.target_name
            target_name_level = crawl_type_level.get(targtename, [])
            crawl_type_level[targtename] = target_name_level
            sortarr = sorted(product_result.pic_paths,key=compared)
            # 获取图片url
            target_name_level.append({
                "pic_urls": sortarr,
                "link": product_result.link,
                "video_link":product_result.video_link,
                "listing": product_result.listing,
                "des": {
                    "description": product_result.description,
                    "extract_info": product_result.extract_info
                },
                "price": product_result.price,
                "specifications": product_result.specifications
            })
        return Resp.ok(data={"task_result": task_result})


    def get_task_list(self, page_info:Page):
        """
        获取任务列表
        """
        # tasks = SpiderTask.select_page(page_info)
        user_id = user_context.get()
        offset = (page_info.current_page - 1) * page_info.page_size
        user = SpiderUser.select_user_by_id(user_id).first()
        if user.role_id == "0":
            res = MySqlUtil.execute_sql(f"select st.*,su.user_name  from spider_task st inner join spider_user su on su.id =st.user_id ORDER by create_time desc LIMIT {page_info.page_size} OFFSET {offset}")
            count = SpiderTask.get_all_count()
        else:
            res = MySqlUtil.execute_sql(f"select st.*,su.user_name  from spider_task st inner join spider_user su on su.id =st.user_id where st.user_id ='{user_id}' ORDER by create_time desc LIMIT {page_info.page_size} OFFSET {offset}")
            count = SpiderTask.get_count()
        task_infos = []
        for task in res:
            task_infos.append({"id":task[0],"task_state":task[2], "task_name":task[4],"create_time":task[5], "finish_time":task[6], "user_name":task[8]})
        return Resp.ok(data={"task_list":task_infos, "total":count, "current_page":page_info.current_page,"page_size":page_info.page_size})

    def get_spider_info(self):
        res = MySqlUtil.execute_sql(f"select * from spider_param where user_id = '{user_context.get()}'")
        if res:
            res = res[0]
            try:
                sko = json.loads(res[5])
            except:
                sko = []
            return Resp.ok(data={"shop_urls":res[1],"key_words":res[2], "product_urls":res[3], "shop_keywords":sko})
        else:
            return Resp.ok(data={"shop_urls":"","key_words":"", "product_urls":"", "shop_keywords":[]})

    def unsatisfied(self, unsatisfied_pic):
        ori_pic_path = unsatisfied_pic.ori
        nowatermark_pic_path = unsatisfied_pic.nowatermark
        MySqlUtil.execute_sql_ori("insert into spider_unsatisfied_pic (id, ori_pic_path, nowatermark_pic_path) values (:id, :or, :no)", {'id':uuid.uuid4().hex, 'or':ori_pic_path, 'no' : nowatermark_pic_path})
        return Resp.ok()

    def login(self, user:User):
        u = SpiderUser.select_user_by_name(user.user_name)
        if u:
            if u.user_pass == user.password:
                return Resp.ok(data={"user_id" : u.id})
            else:
                return Resp.error(msg="密码错误")
        else:
            return Resp.error(msg="用户名不存在")

    def get_user_info(self, user_id):
        u = SpiderUser.select_user_by_id(user_id).first()
        return Resp.ok(data={"id":user_id, "user_name":u.user_name})

    